﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Text.RegularExpressions;

namespace FandangoAids
{
    public partial class FandangoAids : Form
    {
        Communications communications = new Communications();
        Random ran = new Random();
        BackgroundWorker worker = new BackgroundWorker();
        ReviewData reviewData = new ReviewData();
        int progressValue = 0;
        string status = "Status: Waiting";

        class ReviewData
        {
            public string MovieID { get; set; }
            public string ReviewTitle { get; set; }
            public string ReviewText { get; set; }
            public string Gender { get; set; }
        }

        public FandangoAids()
        {
            
            InitializeComponent();
            Storage.Load(log);
            comboBoxGender.SelectedIndex = 0;
            comboBoxMovieID.Text = Storage.MovieID;
            richTextBoxDomain.Text = Storage.DomainSpins;
            LoadItemFromID();
            worker.DoWork += worker_DoWork;
            new Timer { Interval = 100, Enabled = true }.Tick += progressUpdater_Tick;
        }

        void progressUpdater_Tick(object sender, EventArgs e)
        {
            labelStatus.Text = status;
            progressBar1.Value = progressValue;
        }

        void UpdateStatus(string update)
        {
            status = "Status: " + update;
        }

        void worker_DoWork(object sender, DoWorkEventArgs e)
        {
            progressValue = 0;
            string name = GetRandomName();
            UpdateStatus("Fetched name " + name);
            progressValue = 1;

            if (CreateAccount(name))
            {
                name = name.Replace(" ", "");
                UpdateStatus("Created account for " + name);
                progressValue = 2;
            }
            else
            {
                UpdateStatus("Failed creating account for " + name);
                progressValue = 0;
            }

            if (PostReview())
            {
                SerializableDictionary<string, string> links = new SerializableDictionary<string, string>();
                links.Add(reviewData.MovieID, "http://www.fandango.com/movies/1/movieoverview.aspx?mid=" + reviewData.MovieID);
                links.Add(name, "http://www.fandango.com/PublicProfilePage.aspx?cuname=" + name);
                log.PerformLog("Posted review on {LINK} with {LINK}   -   " + reviewData.MovieID + ":" + name, links, WriteEntry: true);
                progressValue = 3;
                UpdateStatus("Completed");
            }
            else
            {
                UpdateStatus(string.Format("Failed to post review on {0} for {1}", reviewData.MovieID, name));
                progressValue = 0;
            }
            
        }

        private void buttonInitiate_Click(object sender, EventArgs e)
        {
            reviewData.MovieID = comboBoxMovieID.Text;
            reviewData.ReviewTitle = textBoxTitle.Text;
            reviewData.ReviewText = textBoxReview.Text.Replace("{DOMAIN}", GetDomainSpin());
            reviewData.Gender = comboBoxGender.SelectedItem.ToString();

            worker.RunWorkerAsync();
        }

        string GetDomainSpin()
        {
            string[] lines = richTextBoxDomain.Lines;
            string domain = "";

            for (int i = 0; i < lines[0].Length; i++)
            {
                domain = domain + lines[ran.Next(0, lines.Length)][i];
            }

            return domain;
        }

        string GetRandomName()
        {
            var data = new Communications.PostData();
            data.AddValue("type", reviewData.Gender == "Male" ? "1" : "2");
            data.AddValue("number", "1");
            data.AddValue("obscurity", "5");
            data.AddValue("Go", "Generate Random Name(s)");
            string nameUrl = "http://www.kleimo.com/random/name.cfm";
            string content = communications.PerformPost(nameUrl, data, nameUrl);
            string name = Regex.Match(content, "1. &nbsp; ([^\"]*)<br>\\s").Groups[1].Value;

            return System.Threading.Thread.CurrentThread.CurrentCulture.TextInfo.ToTitleCase((name.Contains(" ") ? name : GetRandomName()).ToLower());
        }

        bool CreateAccount(string name)
        {
            string url = "https://www.fandango.com/Registration.aspx";

            string registrationPage = communications.PerformGet(url);
            string viewState = Regex.Match(registrationPage, "VIEWSTATE\" value=\"([^\"]*)\" />").Groups[1].Value;
            string eventValidation = Regex.Match(registrationPage, "EVENTVALIDATION\" value=\"([^\"]*)\" />").Groups[1].Value;

            var nameParts = name.Split(' ');
            string firstname = nameParts[0];
            string lastname = nameParts[1];
            string email = firstname + lastname + "101@hotmail.com";

            var data = new Communications.PostData();
            data.AddValue("__EVENTTARGET", "");
            data.AddValue("__EVENTARGUMENT", "");
            data.AddValue("__VIEWSTATE", viewState);
            data.AddValue("headerControl$searchControl$LocationSearchTextBox", "Enter ZIP or City, State");
            data.AddValue("headerControl$searchControl$ctl00$SearchTextBox", "Movies + Actors");
            data.AddValue("FirstNameBox", firstname);
            data.AddValue("LastNameBox", lastname);
            data.AddValue("UserNameBox", firstname + lastname);
            data.AddValue("EmailBox", email);
            data.AddValue("ConfirmEmailBox", email);
            data.AddValue("ZipcodeBox", ran.Next(10000, 91000).ToString());
            data.AddValue("PasswordBox", "fanaids");
            data.AddValue("ConfirmPasswordBox", "fanaids");
            data.AddValue("txtAreaCode", "");
            data.AddValue("txtPhonePart2", "");
            data.AddValue("txtPhonePart3", "");
            data.AddValue("SaveUserButton.x", ran.Next(1, 92).ToString());
            data.AddValue("SaveUserButton.y", ran.Next(1, 20).ToString());
            data.AddValue("newsletterFooter", "Enter E-mail Address");
            data.AddValue("Footer$ctl00$SearchTextBox", "Movies + Actors");
            data.AddValue("__EVENTVALIDATION", eventValidation);

            string result = communications.PerformPost(url, data, allowAutoRedirect: true);

            return result.Contains("View My Public Profile");
        }

        bool PostReview()
        {
            string url = string.Format("http://www.fandango.com/movies/1/moviefanreviews.aspx?mid={0}&mode=write&", reviewData.MovieID);
            string registrationPage = communications.PerformGet(url);
            string viewState = Regex.Match(registrationPage, "VIEWSTATE\" value=\"([^\"]*)\" />").Groups[1].Value;
            string eventValidation = Regex.Match(registrationPage, "EVENTVALIDATION\" value=\"([^\"]*)\" />").Groups[1].Value;
            string setRatingUrl = Regex.Match(registrationPage, "<a data-ajax-href=\"([^\"]*)\">").Groups[1].Value.Replace("updatebuzzes=1", "updaterates=5");
            var setRatingResponse = communications.PerformGet(setRatingUrl, url);

            var data = new Communications.PostData();
            data.AddValue("__EVENTTARGET", "editReviewControl$NormalSaveChangesButton");
            data.AddValue("__EVENTARGUMENT", "");
            data.AddValue("__VIEWSTATE", viewState);
            data.AddValue("headerControl$searchControl$LocationSearchTextBox", "Enter ZIP or City, State");
            data.AddValue("headerControl$searchControl$ctl00$SearchTextBox", "Movies + Actors");
            data.AddValue("editReviewControl$RatingHiddenValue", "5");
            data.AddValue("editReviewControl$BuzzHiddenValue", "");
            data.AddValue("editReviewControl$TitleText", reviewData.ReviewTitle);
            data.AddValue("editReviewControl$BodyText", reviewData.ReviewText);
            data.AddValue("newsletterFooter", "Enter E-mail Address");
            data.AddValue("footerControl$ctl00$SearchTextBox", "Movies + Actors");
            data.AddValue("__EVENTVALIDATION", eventValidation);

            string result = communications.PerformPost(url, data, allowAutoRedirect: true);

            return result.Contains("Thank you for your input!");
        }

        private void buttonSave_Click(object sender, EventArgs e)
        {
            Storage.DomainSpins = richTextBoxDomain.Text;
            Storage.MovieID = comboBoxMovieID.Text;
            if (comboBoxMovieID.Text != "")
            {
                foreach (var x in Storage.Data)
                {
                    if (x[0] == Storage.MovieID)
                    {
                        Storage.Data.Remove(x);
                        break;
                    }
                }
                Storage.Data.Add(new string[] { Storage.MovieID, textBoxTitle.Text, textBoxReview.Text });
            }
            Storage.Save();
            UpdateStatus("Saved");
        }

        private void comboBoxMovieID_DropDown(object sender, EventArgs e)
        {
            comboBoxMovieID.Items.Clear();
            foreach (var t in Storage.Data)
            {
                comboBoxMovieID.Items.Add(t[0]);
            }
        }

        void LoadItemFromID()
        {
            foreach (var x in Storage.Data)
            {
                if (x[0] == comboBoxMovieID.Text)
                {
                    textBoxTitle.Text = x[1];
                    textBoxReview.Text = x[2];
                }
            }
        }

        private void comboBoxMovieID_TextChanged(object sender, EventArgs e)
        {
            LoadItemFromID();
        }

        private void buttonClearEntry_Click(object sender, EventArgs e)
        {
            foreach (var x in Storage.Data)
            {
                if (x[0] == comboBoxMovieID.Text)
                {
                    Storage.Data.Remove(x);
                    break;
                }
            }
            comboBoxMovieID.Text = "";
            textBoxReview.Clear();
            textBoxTitle.Clear();
            UpdateStatus("Entry removed");
        }

        private void label4_Click(object sender, EventArgs e)
        {
            label4.Text = GetDomainSpin();
            Clipboard.SetText(label4.Text);
        }

    }
}
